"""
用户聊天相关的WebSocket处理器
"""
import datetime
from flask import request
from flask_socketio import emit, disconnect, join_room, leave_room
from apps.extensions.init_websocket import socketio
from apps.extensions import db
from apps.modules.admin.models.cms.cms_chat import ChatRecord, ChatSession
import uuid
import logging
logger = logging.getLogger(__name__)

# 跟踪活跃的通话会话（session_id -> sid的映射）
active_call_sessions = {}

@socketio.on('connect', namespace='/chat')
def on_connect():
    """客户端连接"""
    logger.info(f"客户端连接成功: {request.sid}")
    emit('connect_response', {'msg': '连接成功', 'sid': request.sid})


@socketio.on('disconnect', namespace='/chat')
def on_disconnect():
    """客户端断开连接"""
    logger.info(f"客户端断开连接: {request.sid}")
    
    try:
        # 检查是否有正在进行的通话需要取消
        disconnected_session = None
        for session_id, sid in list(active_call_sessions.items()):
            if sid == request.sid:
                disconnected_session = session_id
                del active_call_sessions[session_id]
                break
        
        # 如果有正在进行的通话，通知管理员取消
        if disconnected_session:
            logger.info(f"用户断开连接时取消正在进行的通话: {disconnected_session}")
            emit('voice_call_cancelled', {
                'session_id': disconnected_session,
                'from': 'user',
                'reason': 'disconnect'
            }, namespace='/admin/chat', broadcast=True)
        
        # 通知管理员有用户断开连接
        emit('user_disconnected', {
            'sid': request.sid,
            'disconnect_time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"已通知管理员用户 {request.sid} 断开连接")
        
    except Exception as emit_error:
        logger.error(f"通知管理员用户断开连接失败: {emit_error}")


@socketio.on('user_disconnect_session', namespace='/chat')
def on_user_disconnect_session(data):
    """用户主动断开会话"""
    try:
        session_id = data.get('session_id')
        if session_id:
            # 查找并更新会话状态
            session = ChatSession.query.filter_by(session_id=session_id).first()
            if session:
                session.status = 'closed'
                session.end_time = datetime.datetime.now()
                db.session.commit()
                logger.info(f"会话 {session_id} 状态已更新为关闭")
                
                # 通知管理员会话已关闭
                emit('session_closed', {
                    'session_id': session_id,
                    'msg': '用户主动关闭会话'
                }, namespace='/admin/chat', broadcast=True)
                
    except Exception as e:
        logger.error(f"用户断开会话失败: {e}")
        db.session.rollback()


@socketio.on('voice_call_request', namespace='/chat')
def on_voice_call_request(data):
    """用户发起语音通话请求"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户发起语音通话请求，会话ID: {session_id}, 用户信息: {user_info}")
        
        # 检查管理员是否在线
        from apps.modules.admin.views.cms.chat_websocket import online_admins
        if not online_admins:
            logger.info(f"没有管理员在线，自动取消通话请求: {session_id}")
            
            # 发送自动取消通知
            emit('voice_call_auto_cancelled', {
                'session_id': session_id,
                'message': '客服当前不在线，请在下方输入贵姓和联系方式，客服上线后会及时联系您',
                'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })
            
            # 创建系统消息记录
            chat_record = ChatRecord(
                session_id=session_id,
                sender_type='system',
                content="📞 客服不在线，拨号已自动取消",
                message_type='system',
                create_time=datetime.datetime.now()
            )
            db.session.add(chat_record)
            db.session.commit()
            
            return
        
        # 记录活跃的通话会话
        active_call_sessions[session_id] = request.sid
        logger.info(f"记录活跃通话会话: {session_id} -> {request.sid}")
        
        # 转发通话请求到管理员
        emit('voice_call_request', {
            'session_id': session_id,
            'type': 'incoming',
            'from': 'user',
            'user_info': user_info,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
        # 创建系统消息记录
        user_name = user_info.get('name', '用户')
        system_message = f"📞 {user_name} 发起语音通话请求"
        
        # 保存到数据库
        chat_record = ChatRecord(
            session_id=session_id,
            sender_type='system',
            content=system_message,
            message_type='system',
            create_time=datetime.datetime.now()
        )
        db.session.add(chat_record)
        db.session.commit()
        
        # 发送聊天消息通知
        emit('voice_call_notification', {
            'session_id': session_id,
            'type': 'request',
            'content': system_message,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"发起语音通话请求失败: {e}")
        db.session.rollback()


@socketio.on('voice_call_cancel', namespace='/chat')
def on_voice_call_cancel(data):
    """用户取消语音通话"""
    try:
        session_id = data.get('session_id')
        logger.info(f"用户取消语音通话，会话ID: {session_id}")
        
        # 清理活跃通话会话记录
        if session_id in active_call_sessions:
            del active_call_sessions[session_id]
            logger.info(f"清理活跃通话会话: {session_id}")
        
        # 通知管理员通话被取消
        emit('voice_call_cancelled', {
            'session_id': session_id,
            'from': 'user'
        }, namespace='/admin/chat', broadcast=True)
        
        # 创建系统消息记录
        system_message = "📞 用户取消了通话"
        
        # 保存到数据库
        chat_record = ChatRecord(
            session_id=session_id,
            sender_type='system',
            content=system_message,
            message_type='system',
            create_time=datetime.datetime.now()
        )
        db.session.add(chat_record)
        db.session.commit()
        
        # 发送聊天消息通知
        emit('voice_call_notification', {
            'session_id': session_id,
            'type': 'cancel',
            'content': system_message,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"取消语音通话失败: {e}")
        db.session.rollback()


@socketio.on('voice_call_answer', namespace='/chat')
def on_voice_call_answer(data):
    """用户发送WebRTC应答"""
    try:
        session_id = data.get('session_id')
        answer = data.get('answer')
        logger.info(f"用户发送WebRTC应答，会话ID: {session_id}")
        logger.info(f"Answer数据存在: {answer is not None}")
        if answer:
            logger.info(f"Answer类型: {answer.get('type')}")
        
        # 通知管理员收到WebRTC应答
        emit_result = emit('voice_call_answer', {
            'session_id': session_id,
            'from': 'user',
            'answer': answer
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"向管理员发送 voice_call_answer 事件，emit结果: {emit_result}")
        
    except Exception as e:
        logger.error(f"发送WebRTC应答失败: {e}")
        import traceback
        traceback.print_exc()


@socketio.on('voice_call_accept', namespace='/chat')
def on_voice_call_accept(data):
    """用户接听语音通话"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户接听语音通话，会话ID: {session_id}, 用户: {user_info}")
        
        # 通知管理员用户已接听，让管理员创建WebRTC连接
        emit('voice_call_accepted', {
            'session_id': session_id,
            'from': 'user',
            'user_info': user_info,
            'message': '用户已接听，请创建音频连接'
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"用户接听通知已发送给管理员")
        
    except Exception as e:
        logger.error(f"处理用户接听失败: {e}")
        import traceback
        traceback.print_exc()


@socketio.on('ice_candidate', namespace='/chat')
def on_ice_candidate(data):
    """处理ICE候选"""
    try:
        session_id = data.get('session_id')
        candidate = data.get('candidate')
        sender = data.get('sender')
        logger.info(f"收到ICE候选，会话ID: {session_id}, 发送者: {sender}")
        
        # 转发ICE候选到管理员端
        emit('ice_candidate', {
            'session_id': session_id,
            'candidate': candidate,
            'sender': sender
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"处理ICE候选失败: {e}")


@socketio.on('voice_call_end', namespace='/chat')
def on_voice_call_end(data):
    """用户结束语音通话"""
    try:
        session_id = data.get('session_id')
        logger.info(f"用户结束语音通话，会话ID: {session_id}")
        
        # 清理活跃通话会话记录
        if session_id in active_call_sessions:
            del active_call_sessions[session_id]
            logger.info(f"清理活跃通话会话: {session_id}")
        
        # 通知管理员通话结束
        emit('voice_call_ended', {
            'session_id': session_id,
            'from': 'user'
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"结束语音通话失败: {e}")


@socketio.on('video_call_end', namespace='/chat')
def on_video_call_end(data):
    """用户结束视频通话"""
    try:
        session_id = data.get('session_id')
        logger.info(f"收到用户结束视频通话事件，会话ID: {session_id}")
        
        # 清理活跃视频通话会话记录
        if session_id in active_call_sessions:
            del active_call_sessions[session_id]
            logger.info(f"清理活跃视频通话会话: {session_id}")
        else:
            logger.info(f"会话 {session_id} 不在活跃会话列表中")
        
        # 通知管理员视频通话结束
        emit_result = emit('video_call_ended', {
            'session_id': session_id,
            'from': 'user'
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"视频通话结束事件已发送给管理员，emit结果: {emit_result}")
        
    except Exception as e:
        logger.error(f"结束视频通话失败: {e}")
        import traceback
        traceback.print_exc()


@socketio.on('voice_call_timeout', namespace='/chat')
def on_voice_call_timeout(data):
    """用户呼叫超时（无人接听）"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户呼叫超时，会话ID: {session_id}, 用户: {user_info}")
        
        # 清理活跃通话会话记录
        if session_id in active_call_sessions:
            del active_call_sessions[session_id]
            logger.info(f"清理活跃通话会话: {session_id}")
        
        # 首先发送取消事件，停止管理员端铃声
        emit('voice_call_cancelled', {
            'session_id': session_id,
            'from': 'user',
            'reason': 'timeout'
        }, namespace='/admin/chat', broadcast=True)
        
        # 通知管理员有未接来电
        emit('voice_call_missed', {
            'session_id': session_id,
            'user_info': user_info,
            'type': 'timeout',
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'message': f"用户 {user_info.get('name', '未知')} ({user_info.get('phone', '未知')}) 呼叫超时未接听"
        }, namespace='/admin/chat', broadcast=True)
        
        # 创建系统消息记录
        system_message = "📞 用户呼叫超时未接听"
        
        # 保存到数据库
        chat_record = ChatRecord(
            session_id=session_id,
            sender_type='system',
            content=system_message,
            message_type='system',
            create_time=datetime.datetime.now()
        )
        db.session.add(chat_record)
        db.session.commit()
        
        # 同时发送聊天消息通知
        emit('voice_call_notification', {
            'session_id': session_id,
            'type': 'timeout',
            'content': system_message,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"处理呼叫超时失败: {e}")
        db.session.rollback()


@socketio.on('voice_call_reject', namespace='/chat')
def on_voice_call_reject(data):
    """用户拒绝语音通话"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户拒绝语音通话，会话ID: {session_id}, 用户: {user_info}")
        
        # 清理活跃通话会话记录
        if session_id in active_call_sessions:
            del active_call_sessions[session_id]
            logger.info(f"清理活跃通话会话: {session_id}")
        
        # 通知管理员通话被拒绝
        emit('voice_call_rejected', {
            'session_id': session_id,
            'from': 'user',
            'user_info': user_info
        }, namespace='/admin/chat', broadcast=True)
        
        # 创建系统消息记录
        system_message = "📞 用户拒绝了通话"
        
        # 保存到数据库
        chat_record = ChatRecord(
            session_id=session_id,
            sender_type='system',
            content=system_message,
            message_type='system',
            create_time=datetime.datetime.now()
        )
        db.session.add(chat_record)
        db.session.commit()
        
        # 发送聊天消息通知
        emit('voice_call_notification', {
            'session_id': session_id,
            'type': 'user_reject',
            'content': system_message,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"用户拒绝语音通话失败: {e}")
        db.session.rollback()


@socketio.on('test_connection', namespace='/chat')
def on_test_connection():
    """测试连接"""
    try:
        logger.info(f"收到测试连接请求: {request.sid}")
        emit('test_response', {'msg': '连接测试成功', 'sid': request.sid})
    except Exception as e:
        logger.error(f"测试连接错误: {e}")


@socketio.on('join_chat', namespace='/chat')
def on_join_chat(data):
    """加入聊天会话"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        
        session = None
        
        # 如果提供了session_id，先检查是否存在
        if session_id:
            session = ChatSession.query.filter_by(session_id=session_id).first()
            logger.info(f"查找现有会话 {session_id}: {'找到' if session else '未找到'}")
        
        # 如果会话不存在，创建新会话
        if not session:
            # 生成新的会话ID
            session_id = str(uuid.uuid4())
            logger.info(f"创建新会话: {session_id}")
            
            # 创建新会话
            session = ChatSession(
                session_id=session_id,
                user_name=user_info.get('name', ''),
                user_phone=user_info.get('phone', ''),
                ip_address=request.environ.get('REMOTE_ADDR', ''),
                status='active',
                start_time=datetime.datetime.now(),
                message_count=0
            )
            db.session.add(session)
            logger.info(f"新会话详情: ID={session_id}, 用户名='{session.user_name}', 电话='{session.user_phone}', 状态='{session.status}'")
        else:
            # 更新现有会话信息（如果用户提供了新的信息）
            updated = False
            if user_info.get('name') and user_info.get('name') != session.user_name:
                session.user_name = user_info.get('name')
                updated = True
            if user_info.get('phone') and user_info.get('phone') != session.user_phone:
                session.user_phone = user_info.get('phone')
                updated = True
            
            # 更新会话状态为活跃（如果之前被关闭）
            if session.status != 'active':
                session.status = 'active'
                updated = True
            
            if updated:
                logger.info(f"更新现有会话 {session_id} 的信息: 用户名='{session.user_name}', 电话='{session.user_phone}', 状态='{session.status}'")
        
        # 提交数据库更改
        db.session.commit()
        logger.info(f"会话数据库提交成功: {session_id}")
        
        # 加入房间
        join_room(session_id)
        
        # 获取历史消息
        records = ChatRecord.query.filter_by(session_id=session_id)\
                                .order_by(ChatRecord.create_time.asc()).all()
        
        history_messages = []
        for record in records:
            message_data = {
                'sender_type': record.sender_type,
                'message_type': record.message_type,
                'create_time': record.create_time.strftime('%Y-%m-%d %H:%M:%S')
            }
            
            # 对于图片消息，content字段存储的是base64数据
            if record.message_type == 'image':
                message_data['content'] = '[图片]'
                message_data['image_data'] = record.content  # base64数据作为image_data
            else:
                message_data['content'] = record.content
            
            history_messages.append(message_data)
        
        emit('joined', {
            'session_id': session_id,
            'msg': f'成功加入聊天会话，历史消息: {len(history_messages)} 条'
        })
        
        emit('history_messages', {
            'messages': history_messages
        })
        
        logger.info(f"用户成功加入会话 {session_id}，历史消息数: {len(history_messages)}")
        
    except Exception as e:
        logger.error(f"加入聊天错误: {e}")
        # 回滚数据库事务
        try:
            db.session.rollback()
        except:
            pass
        emit('error', {'msg': '加入聊天失败'})


@socketio.on('send_message', namespace='/chat')
def on_send_message(data):
    """发送消息"""
    try:
        session_id = data.get('session_id')
        content = data.get('content', '').strip()
        message_type = data.get('message_type', 'text')  # 新增：消息类型
        image_data = data.get('image_data')  # 新增：图片数据
        userName = data.get('userName')
        userPhone = data.get('userPhone')

        if not session_id or not content:
            emit('error', {'msg': '会话ID或消息内容不能为空'})
            return
        
        # 确保会话存在
        session = ChatSession.query.filter_by(session_id=session_id).first()
        if not session:
            logger.info(f"发送消息失败: 会话 {session_id} 不存在")
            emit('error', {'msg': '会话不存在，请重新加入聊天'})
            return
        
        # 保存消息记录
        # 对于图片消息，将base64数据存储到content字段
        content_to_save = image_data if message_type == 'image' and image_data else content
        
        new_record = ChatRecord(
            session_id=session_id,
            content=content_to_save,  # 文本消息存文本，图片消息存base64数据
            message_type=message_type,  # 保存消息类型
            user_name=session.user_name,  # 从会话中获取用户名
            user_phone=session.user_phone,  # 从会话中获取用户电话
            sender_type='user',
            ip_address=session.ip_address,  # 从会话中获取IP地址
            user_agent=session.user_agent,  # 从会话中获取用户代理
            create_time=datetime.datetime.now()
        )
        db.session.add(new_record)
        
        # 更新会话消息数和最后更新时间
        session.message_count += 1
        session.update_time = datetime.datetime.now()
        
        db.session.commit()
        
        logger.info(f"用户在会话 {session_id} 发送消息: {content}")
        
        # 准备广播数据
        broadcast_data = {
            'content': content,
            'sender_type': 'user',
            'message_type': message_type,
            'create_time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }
        
        # 如果是图片消息，添加图片数据
        if message_type == 'image' and image_data:
            broadcast_data['image_data'] = image_data
        
        # 广播消息到房间
        emit('new_message', broadcast_data, room=session_id)
        
        # 通知管理员有新消息
        try:
            admin_data = broadcast_data.copy()
            admin_data['session_id'] = session_id
            admin_data['user_name'] = session.user_name
            admin_data['user_phone'] = session.user_phone
            
            emit('new_user_message', admin_data, namespace='/admin/chat', broadcast=True)
            logger.info(f"已通知管理员收到用户消息")
        except Exception as admin_emit_error:
            logger.info(f"通知管理员失败: {admin_emit_error}")
            # 不中断主流程，继续执行
        
    except Exception as e:
        logger.error(f"发送消息失败: {e}")
        db.session.rollback()
        emit('error', {'msg': f'发送消息失败: {str(e)}'})
    finally:
        db.session.close()


@socketio.on('user_typing', namespace='/chat')
def on_user_typing(data):
    """用户正在输入"""
    try:
        session_id = data.get('session_id')
        if session_id:
            emit('user_typing', {
                'session_id': session_id
            }, namespace='/admin/chat', broadcast=True)
    except Exception as e:
        logger.error(f"输入状态错误: {e}")


@socketio.on('user_stop_typing', namespace='/chat')
def on_user_stop_typing(data):
    """用户停止输入"""
    try:
        session_id = data.get('session_id')
        if session_id:
            emit('user_stop_typing', {
                'session_id': session_id
            }, namespace='/admin/chat', broadcast=True)
    except Exception as e:
        logger.error(f"停止输入状态错误: {e}")


@socketio.on('ice_candidate', namespace='/chat')
def on_ice_candidate(data):
    """处理用户ICE候选"""
    try:
        session_id = data.get('session_id')
        candidate = data.get('candidate')
        sender = data.get('sender')
        logger.info(f"收到用户ICE候选，会话ID: {session_id}, 发送者: {sender}")
        
        # 转发ICE候选给管理员
        emit('ice_candidate', {
            'session_id': session_id,
            'candidate': candidate,
            'sender': sender
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"处理用户ICE候选失败: {e}")

@socketio.on('video_call_request', namespace='/chat')
def on_video_call_request(data):
    """用户发起视频通话请求"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户发起视频通话请求，会话ID: {session_id}, 用户信息: {user_info}")
        
        # 检查管理员是否在线
        from apps.modules.admin.views.cms.chat_websocket import online_admins
        if not online_admins:
            logger.info(f"没有管理员在线，自动取消视频通话请求: {session_id}")
            
            # 发送自动取消通知
            emit('video_call_auto_cancelled', {
                'session_id': session_id,
                'message': '客服当前不在线，请在下方输入贵姓和联系方式，客服上线后会及时联系您',
                'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })
            
            # 创建系统消息记录
            chat_record = ChatRecord(
                session_id=session_id,
                sender_type='system',
                content="📹 客服不在线，视频通话已自动取消",
                message_type='system',
                create_time=datetime.datetime.now()
            )
            db.session.add(chat_record)
            db.session.commit()
            
            return
        
        # 记录活跃的视频通话会话
        active_call_sessions[session_id] = request.sid
        logger.info(f"记录活跃视频通话会话: {session_id} -> {request.sid}")
        
        # 转发视频通话请求到管理员
        emit('video_call_request', {
            'session_id': session_id,
            'type': 'incoming',
            'from': 'user',
            'user_info': user_info,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
        # 创建系统消息记录
        user_name = user_info.get('name', '用户')
        system_message = f"📹 {user_name} 发起视频通话请求"
        
        # 保存到数据库
        chat_record = ChatRecord(
            session_id=session_id,
            sender_type='system',
            content=system_message,
            message_type='system',
            create_time=datetime.datetime.now()
        )
        db.session.add(chat_record)
        db.session.commit()
        
        # 发送聊天消息通知
        emit('video_call_notification', {
            'session_id': session_id,
            'type': 'request',
            'content': system_message,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"发起视频通话请求失败: {e}")
        db.session.rollback()

@socketio.on('video_call_cancel', namespace='/chat')
def on_video_call_cancel(data):
    """用户取消视频通话"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户取消视频通话，会话ID: {session_id}")
        
        # 清理活跃视频通话会话记录
        if session_id in active_call_sessions:
            del active_call_sessions[session_id]
            logger.info(f"清理活跃视频通话会话: {session_id}")
        
        # 通知管理员取消视频通话
        emit('video_call_cancelled', {
            'session_id': session_id,
            'from': 'user'
        }, namespace='/admin/chat', broadcast=True)
        
        # 创建系统消息记录
        system_message = "📹 用户取消了视频通话"
        
        # 保存到数据库
        chat_record = ChatRecord(
            session_id=session_id,
            sender_type='system',
            content=system_message,
            message_type='system',
            create_time=datetime.datetime.now()
        )
        db.session.add(chat_record)
        db.session.commit()
        
        # 发送聊天消息通知
        emit('video_call_notification', {
            'session_id': session_id,
            'type': 'cancel',
            'content': system_message,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"取消视频通话失败: {e}")
        db.session.rollback()

@socketio.on('video_call_answer', namespace='/chat')
def on_video_call_answer(data):
    """用户发送视频WebRTC应答"""
    try:
        session_id = data.get('session_id')
        answer = data.get('answer')
        logger.info(f"用户发送视频WebRTC应答，会话ID: {session_id}")
        logger.info(f"Answer数据存在: {answer is not None}")
        if answer:
            logger.info(f"Answer类型: {answer.get('type')}")
        
        # 通知管理员收到视频WebRTC应答
        emit_result = emit('video_call_answer', {
            'session_id': session_id,
            'from': 'user',
            'answer': answer
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"视频WebRTC应答转发给管理员，发送结果: {emit_result}")
        
    except Exception as e:
        logger.error(f"发送视频WebRTC应答失败: {e}")

@socketio.on('video_call_accept', namespace='/chat')
def on_video_call_accept(data):
    """用户接听视频通话（包括回拨）"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户接听视频通话，会话ID: {session_id}, 用户信息: {user_info}")
        
        # 通知管理员用户已接听视频通话
        emit('video_call_accepted', {
            'session_id': session_id,
            'from': 'user',
            'user_info': user_info,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"用户接听视频通话失败: {e}")

@socketio.on('video_call_timeout', namespace='/chat')
def on_video_call_timeout(data):
    """用户视频通话超时（无人接听）"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户视频通话超时，会话ID: {session_id}, 用户: {user_info}")

        # 清理活跃视频通话会话记录
        if session_id in active_call_sessions:
            del active_call_sessions[session_id]
            logger.info(f"清理活跃视频通话会话: {session_id}")

        # 首先发送取消事件，停止管理员端铃声
        emit('video_call_cancelled', {
            'session_id': session_id,
            'from': 'user',
            'reason': 'timeout'
        }, namespace='/admin/chat', broadcast=True)

        # 通知管理员有未接视频来电
        emit('video_call_missed', {
            'session_id': session_id,
            'user_info': user_info,
            'type': 'timeout',
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'message': f"用户 {user_info.get('name', '未知')} ({user_info.get('phone', '未知')}) 视频通话超时未接听"
        }, namespace='/admin/chat', broadcast=True)

        # 创建系统消息记录
        system_message = "📹 用户视频通话超时未接听"

        # 保存到数据库
        chat_record = ChatRecord(
            session_id=session_id,
            sender_type='system',
            content=system_message,
            message_type='system',
            create_time=datetime.datetime.now()
        )
        db.session.add(chat_record)
        db.session.commit()

        # 同时发送聊天消息通知
        emit('video_call_notification', {
            'session_id': session_id,
            'type': 'timeout',
            'content': system_message,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)

    except Exception as e:
        logger.error(f"处理视频通话超时失败: {e}")
        db.session.rollback()

@socketio.on('video_ice_candidate', namespace='/chat')
def on_video_ice_candidate(data):
    """处理用户视频ICE候选"""
    try:
        session_id = data.get('session_id')
        candidate = data.get('candidate')
        sender = data.get('sender')
        logger.info(f"收到用户视频ICE候选，会话ID: {session_id}, 发送者: {sender}")
        
        # 转发视频ICE候选给管理员
        emit('video_ice_candidate', {
            'session_id': session_id,
            'candidate': candidate,
            'sender': sender
        }, namespace='/admin/chat', broadcast=True)
        
    except Exception as e:
        logger.error(f"处理用户视频ICE候选失败: {e}")


# 桌面共享相关处理器

@socketio.on('desktop_share_request', namespace='/chat')
def on_desktop_share_request(data):
    """用户发起桌面共享请求"""
    try:
        session_id = data.get('session_id')
        user_info = data.get('user_info', {})
        logger.info(f"用户发起桌面共享请求，会话ID: {session_id}, 用户信息: {user_info}")
        
        # 检查管理员是否在线
        from apps.modules.admin.views.cms.chat_websocket import online_admins
        if not online_admins:
            logger.info(f"没有管理员在线，自动取消桌面共享请求: {session_id}")
            
            # 发送自动取消通知
            emit('desktop_share_auto_cancelled', {
                'session_id': session_id,
                'message': '客服当前不在线，无法接收桌面共享',
                'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            })
            
            # 记录系统消息到数据库
            try:
                session = ChatSession.query.filter_by(session_id=session_id).first()
                if session:
                    system_record = ChatRecord(
                        session_id=session_id,
                        sender_type='system',
                        message_type='system',
                        content='桌面共享请求失败：客服不在线',
                        create_time=datetime.datetime.now()
                    )
                    db.session.add(system_record)
                    db.session.commit()
                    logger.info(f"桌面共享失败系统消息已记录到数据库")
            except Exception as db_error:
                logger.error(f"记录桌面共享失败系统消息失败: {db_error}")
                db.session.rollback()
            
            return
        
        # 记录桌面共享请求到数据库
        try:
            session = ChatSession.query.filter_by(session_id=session_id).first()
            if session:
                system_record = ChatRecord(
                    session_id=session_id,
                    sender_type='system',
                    message_type='system',
                    content='用户发起桌面共享请求',
                    create_time=datetime.datetime.now()
                )
                db.session.add(system_record)
                db.session.commit()
                logger.info(f"桌面共享请求系统消息已记录到数据库")
        except Exception as db_error:
            logger.error(f"记录桌面共享请求系统消息失败: {db_error}")
            db.session.rollback()
        
        # 通知管理员有桌面共享请求
        emit('desktop_share_incoming', {
            'session_id': session_id,
            'user_info': user_info,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"桌面共享请求已发送给管理员")
        
    except Exception as e:
        logger.error(f"处理桌面共享请求失败: {e}")
        import traceback
        traceback.print_exc()


@socketio.on('desktop_share_cancel', namespace='/chat')
def on_desktop_share_cancel(data):
    """用户取消桌面共享"""
    try:
        session_id = data.get('session_id')
        logger.info(f"用户取消桌面共享，会话ID: {session_id}")
        
        # 记录取消消息到数据库
        try:
            session = ChatSession.query.filter_by(session_id=session_id).first()
            if session:
                system_record = ChatRecord(
                    session_id=session_id,
                    sender_type='system',
                    message_type='system',
                    content='用户取消桌面共享',
                    create_time=datetime.datetime.now()
                )
                db.session.add(system_record)
                db.session.commit()
                logger.info(f"桌面共享取消系统消息已记录到数据库")
        except Exception as db_error:
            logger.error(f"记录桌面共享取消系统消息失败: {db_error}")
            db.session.rollback()
        
        # 通知管理员桌面共享已取消
        emit('desktop_share_cancelled', {
            'session_id': session_id,
            'from': 'user',
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"桌面共享取消事件已发送给管理员")
        
    except Exception as e:
        logger.error(f"处理桌面共享取消失败: {e}")
        import traceback
        traceback.print_exc()


@socketio.on('desktop_share_end', namespace='/chat')
def on_desktop_share_end(data):
    """用户结束桌面共享"""
    try:
        session_id = data.get('session_id')
        logger.info(f"用户结束桌面共享，会话ID: {session_id}")
        
        # 记录结束消息到数据库
        try:
            session = ChatSession.query.filter_by(session_id=session_id).first()
            if session:
                system_record = ChatRecord(
                    session_id=session_id,
                    sender_type='system',
                    message_type='system',
                    content='桌面共享已结束',
                    create_time=datetime.datetime.now()
                )
                db.session.add(system_record)
                db.session.commit()
                logger.info(f"桌面共享结束系统消息已记录到数据库")
        except Exception as db_error:
            logger.error(f"记录桌面共享结束系统消息失败: {db_error}")
            db.session.rollback()
        
        # 通知管理员桌面共享已结束
        emit('desktop_share_ended', {
            'session_id': session_id,
            'from': 'user',
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"桌面共享结束事件已发送给管理员")
        
    except Exception as e:
        logger.error(f"处理桌面共享结束失败: {e}")
        import traceback
        traceback.print_exc()


@socketio.on('desktop_share_ice_candidate', namespace='/chat')
def on_desktop_share_ice_candidate(data):
    """处理桌面共享ICE候选"""
    try:
        session_id = data.get('session_id')
        candidate = data.get('candidate')
        sender = data.get('sender', 'user')
        logger.info(f"收到桌面共享ICE候选，会话ID: {session_id}, 发送者: {sender}")
        
        # 转发ICE候选给管理员
        emit('desktop_share_ice_candidate', {
            'session_id': session_id,
            'candidate': candidate,
            'sender': sender
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"桌面共享ICE候选已转发给管理员")
        
    except Exception as e:
        logger.error(f"处理桌面共享ICE候选失败: {e}")
        import traceback
        traceback.print_exc()


@socketio.on('desktop_share_timeout', namespace='/chat')
def on_desktop_share_timeout(data):
    """桌面共享超时"""
    try:
        session_id = data.get('session_id')
        logger.info(f"桌面共享超时，会话ID: {session_id}")
        
        # 记录超时消息到数据库
        try:
            session = ChatSession.query.filter_by(session_id=session_id).first()
            if session:
                system_record = ChatRecord(
                    session_id=session_id,
                    sender_type='system',
                    message_type='system',
                    content='桌面共享请求超时，无人接听',
                    create_time=datetime.datetime.now()
                )
                db.session.add(system_record)
                db.session.commit()
                print(f"桌面共享超时系统消息已记录到数据库")
        except Exception as db_error:
            logger.error(f"记录桌面共享超时系统消息失败: {db_error}")
            db.session.rollback()
        
        # 通知管理员桌面共享超时
        emit('desktop_share_missed', {
            'session_id': session_id,
            'type': 'timeout',
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'message': '桌面共享请求超时，无人接听'
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"桌面共享超时事件已发送给管理员")
        
    except Exception as e:
        logger.error(f"处理桌面共享超时失败: {e}")
        import traceback
        traceback.print_exc()


@socketio.on('desktop_share_offer', namespace='/chat')
def on_desktop_share_offer(data):
    """处理桌面共享offer并转发给管理员"""
    try:
        session_id = data.get('session_id')
        offer = data.get('offer')
        user_info = data.get('user_info', {})
        logger.info(f"收到用户桌面共享offer，会话ID: {session_id}")
        
        # 转发offer给管理员
        emit('desktop_share_offer_received', {
            'session_id': session_id,
            'offer': offer,
            'user_info': user_info,
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }, namespace='/admin/chat', broadcast=True)
        
        logger.info(f"桌面共享offer已转发给管理员")
        
    except Exception as e:
        logger.error(f"处理桌面共享offer失败: {e}")
        import traceback
        traceback.print_exc() 